<template>
  <div class="batch-selector-container">
    <div class="batch-cell" @click.stop="handleClick">
      <slot name="reference">
        <el-input :value="modelValue" @input="handleInputChange" size="small" readonly :placeholder="placeholder"></el-input>
        <el-icon class="batch-icon"><arrow-down /></el-icon>
      </slot>
    </div>
    
    <teleport to="body">
      <div v-if="popoverVisible" class="batch-selector-popper" :style="popperStyle" v-click-outside="closePopper">
        <div class="batch-popover-content" @click.stop>
          <div class="batch-popover-header">
            <span class="title">{{ title }}</span>
            <div class="search-box">
              <el-input v-model="searchKeyword" :placeholder="searchPlaceholder" size="small" clearable>
                <template #suffix>
                  <el-icon><search /></el-icon>
                </template>
              </el-input>
              <el-button v-if="showSearchButton" style="margin-left: 20px;" type="primary" size="small" @click="handleSearch">查询</el-button>
            </div>
          </div>
          <el-table
            :data="filteredData"
            :height="tableHeight"
            style="width: 100%"
            border
            highlight-current-row
            @row-click="handleRowClick"
          >
            <el-table-column type="index" label="#" width="50"></el-table-column>
            <slot name="columns">
              <el-table-column :prop="propMap.batchNo" :label="labelMap.batchNo" min-width="120"></el-table-column>
              <el-table-column :prop="propMap.productionDate" :label="labelMap.productionDate" min-width="100"></el-table-column>
              <el-table-column :prop="propMap.expiryDate" :label="labelMap.expiryDate" min-width="100"></el-table-column>
              <el-table-column :prop="propMap.quantity" :label="labelMap.quantity" width="70"></el-table-column>
            </slot>
            <el-table-column fixed="right" label="操作" width="50">
              <template #header>
                <el-icon @click.stop="handleAddBatch" size="25"><circle-plus /></el-icon>
              </template>
              <template #default="{ row, $index }">
                <el-icon @click.stop="handleRemoveBatch($index)" size="25"><remove /></el-icon>
              </template>
            </el-table-column>
          </el-table>
        </div>
      </div>
    </teleport>
  </div>
</template>

<script setup>
import { ref, computed, watch, onMounted, onBeforeUnmount, nextTick } from 'vue';
import { Search, ArrowDown, CirclePlus, Remove } from '@element-plus/icons-vue';
import { ElMessage } from 'element-plus';

const props = defineProps({
  // 模型值，用于双向绑定
  modelValue: {
    type: String,
    default: ''
  },
  // 数据源
  data: {
    type: Array,
    default: () => []
  },
  // 占位符
  placeholder: {
    type: String,
    default: '点击选择批次号'
  },
  // 搜索框占位符
  searchPlaceholder: {
    type: String,
    default: '搜索批次号'
  },
  // 弹出框标题
  title: {
    type: String,
    default: '批次信息'
  },
  // 弹出框宽度
  width: {
    type: Number,
    default: 600
  },
  // 弹出框位置
  placement: {
    type: String,
    default: 'bottom'
  },
  // 表格高度
  tableHeight: {
    type: Number,
    default: 200
  },
  // 是否显示搜索按钮
  showSearchButton: {
    type: Boolean,
    default: true
  },
  // 字段映射
  propMap: {
    type: Object,
    default: () => ({
      batchNo: 'batchNo',
      productionDate: 'productionDate',
      expiryDate: 'expiryDate',
      quantity: 'quantity'
    })
  },
  // 标签映射
  labelMap: {
    type: Object,
    default: () => ({
      batchNo: '商品批次号',
      productionDate: '生产日期',
      expiryDate: '到期日期',
      quantity: '数量'
    })
  },
  // 搜索字段
  searchField: {
    type: String,
    default: 'batchNo'
  }
});

const emit = defineEmits(['update:modelValue', 'select', 'search', 'add', 'remove']);

// 弹出框显示状态
const popoverVisible = ref(false);
// 搜索关键字
const searchKeyword = ref('');

// 过滤后的数据
const filteredData = computed(() => {
  if (!searchKeyword.value) {
    return props.data;
  }
  const field = props.propMap[props.searchField] || props.searchField;
  return props.data.filter(item => 
    String(item[field]).toLowerCase().includes(searchKeyword.value.toLowerCase())
  );
});

// 自定义点击外部指令
const vClickOutside = {
  mounted(el, binding) {
    el._clickOutside = (event) => {
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event);
      }
    };
    document.addEventListener('click', el._clickOutside);
  },
  unmounted(el) {
    document.removeEventListener('click', el._clickOutside);
  }
};

// 弹窗样式
const popperStyle = ref({
  position: 'fixed',
  zIndex: 2000,
  background: '#fff',
  borderRadius: '4px',
  boxShadow: '0 2px 12px 0 rgba(0, 0, 0, 0.1)',
  border: '1px solid #e4e7ed',
  padding: '12px',
  width: `${props.width}px`,
  top: '0px',
  left: '0px'
});

// 处理点击事件
const handleClick = (event) => {
  popoverVisible.value = !popoverVisible.value;
  
  if (popoverVisible.value) {
    nextTick(() => {
      positionPopper(event.target);
    });
  }
  
  console.log('批次号弹窗: 点击触发元素，当前状态:', popoverVisible.value);
};

// 关闭弹窗
const closePopper = () => {
  popoverVisible.value = false;
  console.log('批次号弹窗: 点击外部区域，关闭弹窗');
};

// 定位弹窗
const positionPopper = (triggerEl) => {
  if (!triggerEl) return;
  
  const rect = triggerEl.getBoundingClientRect();
  const scrollTop = window.scrollY || document.documentElement.scrollTop;
  const scrollLeft = window.scrollX || document.documentElement.scrollLeft;
  
  popperStyle.value.top = `${rect.bottom + scrollTop}px`;
  popperStyle.value.left = `${rect.left + scrollLeft}px`;
};

// 处理行点击事件
const handleRowClick = (row) => {
  const batchNoField = props.propMap.batchNo;
  emit('update:modelValue', row[batchNoField]);
  emit('select', row);
  popoverVisible.value = false;
};

// 处理搜索
const handleSearch = () => {
  emit('search', searchKeyword.value);
};

// 处理输入变化
const handleInputChange = (val) => {
  emit('update:modelValue', val);
};

// 处理添加批次
const handleAddBatch = () => {
  emit('add');
};

// 处理移除批次
const handleRemoveBatch = (index) => {
  const item = filteredData.value[index];
  emit('remove', index, item);
};

// 监听modelValue的变化
watch(() => props.modelValue, (newVal) => {
  if (!newVal) {
    searchKeyword.value = '';
  }
});
</script>

<style lang="scss" scoped>
.batch-selector-container {
  position: relative;
  display: inline-block;
  width: 100%;
}

.batch-selector-popper {
  background: #fff;
  border-radius: 4px;
  box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.1);
  padding: 12px;
  z-index: 2000;
  border: 1px solid #e4e7ed;
}

.batch-cell {
  display: flex;
  align-items: center;
  position: relative;
  cursor: pointer;
  width: 100%;
  border: 1px solid #DCDFE6;
  border-radius: 4px;
  transition: all 0.2s;
  min-height: 32px;
  
  &:hover {
    border-color: var(--el-color-primary);
    background-color: #f5f7fa;
  }
  
  .el-input {
    width: 100%;
    
    :deep(.el-input__wrapper) {
      box-shadow: none !important;
      padding-right: 25px;
      background-color: transparent;
    }
  }
  
  .batch-icon {
    position: absolute;
    right: 8px;
    color: var(--el-color-primary);
    pointer-events: none;
  }
}

:deep(.batch-popover) {
  padding: 0;
  
  .el-popover__title {
    margin: 0;
    padding: 0;
  }
}

.batch-popover-content {
  .batch-popover-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 8px 12px;
    border-bottom: 1px solid #ebeef5;
    margin-bottom: 8px;
    
    .title {
      font-weight: bold;
      font-size: 14px;
    }
    
    .search-box {
      width: 280px;
      display: flex;
      flex-direction: row;
      align-items: center;
    }
  }
  
  .el-table {
    margin-bottom: 8px;
    
    :deep(tbody tr) {
      cursor: pointer;
      
      &:hover > td {
        background-color: #f5f7fa;
      }
    }

    .el-icon {
      cursor: pointer;
      &:hover {
        color: var(--el-color-primary);
      }
    }
  }
}
</style> 